package com.cdck.safe.dete.common.util;

import com.alibaba.excel.metadata.Head;
import com.alibaba.excel.metadata.data.WriteCellData;
import com.alibaba.excel.write.handler.CellWriteHandler;
import com.alibaba.excel.write.handler.context.CellWriteHandlerContext;
import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
import com.alibaba.excel.write.metadata.holder.WriteTableHolder;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddress;

import java.util.List;

public class excelMergeUtils implements CellWriteHandler {
    /**
     * 需要合并列的下标，从0开始
     */
    private  int[] mergeColumnIndex;
    /**
     * 从第几行开始合并，表头下标为0
     */
    private  int mergeRowIndex;

    public excelMergeUtils(int mergeRowIndex, int[] mergeColumnIndex) {
        this.mergeRowIndex = mergeRowIndex;
        this.mergeColumnIndex = mergeColumnIndex;

    }

    @Override
    public void beforeCellCreate(CellWriteHandlerContext context) {

    }

    @Override
    public void beforeCellCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Row row, Head head, Integer columnIndex, Integer relativeRowIndex, Boolean isHead) {

    }

    @Override
    public void afterCellCreate(CellWriteHandlerContext context) {

    }

    @Override
    public void afterCellCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) {

    }

    @Override
    public void afterCellDataConverted(CellWriteHandlerContext context) {


    }

    @Override
    public void afterCellDataConverted(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, WriteCellData<?> cellData, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) {
    }

    @Override
    public void afterCellDispose(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder,
                                 List<WriteCellData<?>> cellDataList,
                                 Cell cell, Head head,
                                 Integer relativeRowIndex,
                                 Boolean isHead) {

    }

    private void mergeWithPrevRow(WriteSheetHolder writeSheetHolder, Cell cell, int curRowIndex, int curColIndex) {
        //获取当前行的当前列的数据和上一行的当前列列数据，通过上一行数据是否相同进行合并
        Object curData = cell.getCellTypeEnum() == CellType.STRING ? cell.getStringCellValue() :
                cell.getNumericCellValue();
        Row preRow = cell.getSheet().getRow(curRowIndex - 1);
        if (preRow == null) {
            // 当获取不到上一行数据时，使用缓存sheet中数据
            preRow = writeSheetHolder.getCachedSheet().getRow(curRowIndex - 1);
        }
        Cell preCell = preRow.getCell(curColIndex);
        Object preData = preCell.getCellTypeEnum() == CellType.STRING ? preCell.getStringCellValue() :
                preCell.getNumericCellValue();
        // 比较当前行的第一列的单元格与上一行是否相同，相同合并当前单元格与上一行
        if (curData.equals(preData)) {
            Sheet sheet = writeSheetHolder.getSheet();
            List<CellRangeAddress> mergeRegions = sheet.getMergedRegions();
            boolean isMerged = false;
            for (int i = 0; i < mergeRegions.size() && !isMerged; i++) {
                CellRangeAddress cellRangeAddr = mergeRegions.get(i);
                // 若上一个单元格已经被合并，则先移出原有的合并单元，再重新添加合并单元
                if (cellRangeAddr.isInRange(curRowIndex - 1, curColIndex)) {
                    sheet.removeMergedRegion(i);
                    cellRangeAddr.setLastRow(curRowIndex);
                    sheet.addMergedRegion(cellRangeAddr);
                    isMerged = true;
                }
            }
            // 若上一个单元格未被合并，则新增合并单元
            if (!isMerged) {
                CellRangeAddress cellRangeAddress = new CellRangeAddress(curRowIndex - 1, curRowIndex, curColIndex,
                        curColIndex);
                sheet.addMergedRegion(cellRangeAddress);
            }
        }
    }

    @Override
    public void afterCellDispose(CellWriteHandlerContext context) {
        Cell cell = context.getCell();
        WriteSheetHolder writeSheetHolder = context.getWriteSheetHolder();
        //当前行
        int curRowIndex = cell.getRowIndex();
        //当前列
        int curColIndex = cell.getColumnIndex();
        Workbook workbook = context.getWriteWorkbookHolder().getWorkbook();
        if (curRowIndex >= mergeRowIndex) {
            for (int i = 0; i < mergeColumnIndex.length; i++) {
                if (curColIndex == mergeColumnIndex[i]) {
                    mergeWithPrevRow(writeSheetHolder, cell, curRowIndex, curColIndex);
                    // 这里千万记住 想办法能复用的地方把他缓存起来 一个表格最多创建6W个样式 , 不同单元格尽量传同一个 cellStyle
                    cell.getRow().setHeightInPoints(30);
                    CellStyle cellStyle = workbook.createCellStyle();
                    Font writeFont = workbook.createFont();
                    //字体设置成红色
                    writeFont.setColor(IndexedColors.BLACK1.getIndex());
                    cellStyle.setFont(writeFont);
                    cellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
                    cellStyle.setVerticalAlignment(VerticalAlignment.CENTER); //居中对齐
                    cell.setCellStyle(cellStyle);
                    // 由于这里没有指定dataformat 最后展示的数据 格式可能会不太正确
                    // 这里要把 WriteCellData的样式清空， 不然后面还有一个拦截器 FillStyleCellWriteHandler 默认会将 WriteCellStyle 设置到
                    // cell里面去 会导致自己设置的不一样
                    context.getFirstCellData().setWriteCellStyle(null);
                    break;
                }
            }
        }else {
            // 这里千万记住 想办法能复用的地方把他缓存起来 一个表格最多创建6W个样式 , 不同单元格尽量传同一个 cellStyle
            CellStyle cellStyle = workbook.createCellStyle();
            cell.getRow().setHeightInPoints(50);//设置行高
            Font writeFont = workbook.createFont();
            //字体设置成红色
            writeFont.setColor(IndexedColors.BLUE_GREY.getIndex());//字体颜色
            writeFont.setBold(true);//加粗字体
            writeFont.setFontHeight((short) (18*20));//设置字体大小  18号
            writeFont.setFontName("微软雅黑");
            cellStyle.setFont(writeFont);
            cellStyle.setAlignment(HorizontalAlignment.CENTER);
            cellStyle.setVerticalAlignment(VerticalAlignment.CENTER); //居中对齐
//            cellStyle.setFillForegroundColor(IndexedColors.BLUE.getIndex());//设置背景色
//            cellStyle.setFillPattern(FillPatternType.THICK_FORWARD_DIAG);

            cell.setCellStyle(cellStyle);
            // 由于这里没有指定dataformat 最后展示的数据 格式可能会不太正确
            // 这里要把 WriteCellData的样式清空， 不然后面还有一个拦截器 FillStyleCellWriteHandler 默认会将 WriteCellStyle 设置到
            // cell里面去 会导致自己设置的不一样
            context.getFirstCellData().setWriteCellStyle(null);
        }


    }
}
